import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type InternalAxiosRequestConfig } from 'axios';
import { showToast } from '@/components/Toast';
import { getToken, clearToken } from '@/utils/auth';

// 定义响应数据结构
export interface ApiResponse<T = any> {
  code: number;
  message: string;
  data: T;
}

class Request {
  private instance: AxiosInstance;
  
  constructor() {
    this.instance = axios.create({
      baseURL: import.meta.env.VITE_API_BASE_URL,
      timeout: 10000,
      headers: {
        'Content-Type': 'application/json'
      }
    });
    
    this.setupInterceptors();
  }
  
  // 设置拦截器
  private setupInterceptors() {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        const token = getToken();
        if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );
    
    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        const { code, message } = response.data;
        
        // 业务逻辑错误处理
        if (code !== 0) {
          showToast(message || '请求失败');
          return Promise.reject(new Error(message || 'Error'));
        }
        
        return response.data;
      },
      (error) => {
        // HTTP状态码错误处理
        if (error.response) {
          switch (error.response.status) {
            case 401:
              clearToken();
              showToast('登录已过期，请重新登录');
              // 跳转到登录页的逻辑
              break;
            case 403:
              showToast('没有权限访问');
              break;
            case 500:
              showToast('服务器错误');
              break;
            default:
              showToast(error.response.data.message || '请求错误');
          }
        }
        return Promise.reject(error);
      }
    );
  }
  
  // 封装请求方法
  public request<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.instance.request(config);
  }
  
  public get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.get(url, config);
  }
  
  public post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.post(url, data, config);
  }
  
  public put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.put(url, data, config);
  }
  
  public delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.delete(url, config);
  }
}

const http = new Request();

export default http;
